Skip to content

Implement opacity for popups#19272

Closed
mattn wants to merge 3 commits intovim:masterfrom
mattn:popup-opacity
Closed

Implement opacity for popups#19272
mattn wants to merge 3 commits intovim:masterfrom
mattn:popup-opacity

Conversation

@mattn
Copy link
Copy Markdown
Member

@mattn mattn commented Jan 29, 2026

Popup windows in Vim currently have no transparency support. Users cannot create semi-transparent overlays that allow underlying text to be visible through the popup.

So, add a new opacity option for popup windows that controls transparency level.

image image
2026-01-29.130110.mp4
### Usage

```vim
" Create a popup with 50% opacity (semi-transparent)
let winid = popup_create('Semi-transparent text', #{
    \ line: 5,
    \ col: 10,
    \ opacity: 50,
    \ })

" Change opacity dynamically
call popup_setoptions(winid, #{opacity: 80})

" Get current opacity value
echo popup_getoptions(winid).opacity

Opacity values

  • 0 - Fully transparent (background text fully visible)
  • 100 - Fully opaque (default, no transparency)
  • 1-99 - Partially transparent

Requirements

  • Requires 'termguicolors' to be enabled for the blending effect to work

@mattn mattn force-pushed the popup-opacity branch 2 times, most recently from 4191f25 to 775e56c Compare January 29, 2026 11:36
@chrisbra
Copy link
Copy Markdown
Member

Thanks, can you please squash and rebase? I'd like to see the CI output again.

closes: vim#19272

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
@chrisbra
Copy link
Copy Markdown
Member

Hm, it fails for tiny versions. I suspect we need this on top of it?

diff --git a/src/highlight.c b/src/highlight.c
index cc7715217..9ee925a02 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -3081,6 +3081,7 @@ hl_combine_attr(int char_attr, int prim_attr)
     return get_attr_entry(&term_attr_table, &new_en);
 }

+# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
 /*
  * Blend two RGB colors based on blend value (0-100).
  * blend: 0=use popup color, 100=use background color
@@ -3118,6 +3119,7 @@ blend_colors(guicolor_T popup_color, guicolor_T bg_color, int blend_val)

     return (r << 16) | (g << 8) | b;
 }
+#endif

 /*
  * Blend attributes for popup windows with opacity.

@chrisbra
Copy link
Copy Markdown
Member

Thanks. I have included this now, fixing the conflict, please double verify. The reason for no screendump test is that this requires 'termguicolors', right?

@chrisbra chrisbra closed this in 95e8faa Feb 18, 2026
@chrisbra
Copy link
Copy Markdown
Member

I think this caused the following Coverity warnings:

** CID 1681431:       Incorrect expression  (IDENTICAL_BRANCHES)
/src/highlight.c: 3223           in hl_blend_attr()


_____________________________________________________________________________________________
*** CID 1681431:         Incorrect expression  (IDENTICAL_BRANCHES)
/src/highlight.c: 3223             in hl_blend_attr()
3217                popup_aep = syn_cterm_attr2entry(popup_attr);
3218                if (popup_aep != NULL)
3219                {
3220                    // Blend foreground color
3221                    if (popup_aep->ae_u.cterm.fg_color > 0)
3222                    {
>>>     CID 1681431:         Incorrect expression  (IDENTICAL_BRANCHES)
>>>     The same code is executed regardless of whether "new_en.ae_u.cterm.fg_color > 0" is true, because the "then" and "else" branches are identical. Should one of the branches be modified, or the entire "if" statement replaced?
3223                        if (new_en.ae_u.cterm.fg_color > 0)
3224                            new_en.ae_u.cterm.fg_color = popup_aep->ae_u.cterm.fg_color;
3225                        else
3226                            new_en.ae_u.cterm.fg_color = popup_aep->ae_u.cterm.fg_color;
3227                    }
3228                    // Use popup background color (cterm colors don't support blending)

** CID 1681430:       Integer handling issues  (INTEGER_OVERFLOW)
/src/screen.c: 845           in screen_line()


_____________________________________________________________________________________________
*** CID 1681430:         Integer handling issues  (INTEGER_OVERFLOW)
/src/screen.c: 845             in screen_line()
839             else if (  p_wiv
840     #ifdef FEAT_GUI
841                     && !gui.in_use
842     #endif
843                     && col + coloff > 0)
844             {
>>>     CID 1681430:         Integer handling issues  (INTEGER_OVERFLOW)
>>>     Expression "off_to - 1U", where "off_to" is known to be equal to 0, underflows the type of "off_to - 1U", which is type "unsigned int".
845                 if (ScreenAttrs[off_to] == ScreenAttrs[off_to - 1])
846                 {
847                     /*
848                      * Don't output stop-highlight when moving the cursor, it will
849                      * stop the highlighting when it should continue.
850                      */

can you please have a look @mattn ?

chrisbra added a commit that referenced this pull request Feb 21, 2026
Problem:  Redundant code in hl_blend_attr()
          (Coverity, after v9.2.0017)
Solution: Remove redundant if/else logic, remove redundant braces.

related: #19272

Signed-off-by: Christian Brabandt <cb@256bit.org>
chrisbra added a commit to chrisbra/vim that referenced this pull request Feb 21, 2026
Problem:  In screen_line(), there is a potential integer underflow when
          accessing ScreenAttrs[off_to - 1] if off_to is zero.
          (Coverity CID 1681430, after v9.2.0017)
Solution: Add a check to ensure off_to > 0 before accessing the
          previous attribute index.

related: vim#19272

Signed-off-by: Christian Brabandt <cb@256bit.org>
chrisbra pushed a commit that referenced this pull request Feb 21, 2026
Problem:  syntax highlighting lost in popup with opacity lower than 100
          (after v9.2.0017)
Solution: Before blending, combine the popup's window color attribute
          with the character's own attribute using hl_combine_attr()
          (Yasuhiro Matsumoto).

related: #19272
closes:  #19478

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
chrisbra added a commit that referenced this pull request Feb 21, 2026
Problem:  In screen_line(), there is a potential integer underflow when
          accessing ScreenAttrs[off_to - 1] if off_to is zero.
          (Coverity CID 1681430, after v9.2.0017)
Solution: Add a check to ensure off_to > 0 before accessing the
          previous attribute index.

related: #19272
closes:  #19479

Signed-off-by: Christian Brabandt <cb@256bit.org>
@lilydjwg
Copy link
Copy Markdown
Contributor

Hi, can you check #19485 which happens since this patch?

@mattn mattn deleted the popup-opacity branch March 17, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants